// Package entities  entityBase -----------------------------
// @file      : avatar.go
// @author    : WuZhouHai
// @contact   : wzh200x@126.com
// @time      : 2024/4/12 17:21
// @desc      :
// -------------------------------------------
package entities

import (
	"github.com/gogf/gf/v2/errors/gerror"
	"phoenix/apps/examples/phoenix_app_dwys/defines"
	entityType2 "phoenix/apps/examples/phoenix_app_dwys/defines/entityType"
	"phoenix/apps/examples/phoenix_app_dwys/entities/module/avatar"
	"phoenix/apps/examples/phoenix_app_dwys/model/entity"
	avatar2 "phoenix/apps/examples/phoenix_app_dwys/model/entityModule/avatar"
	"phoenix/apps/examples/phoenix_app_dwys/protocol/golang/protos"
	"phoenix/phoenix/common/logger"
	"phoenix/phoenix/defines/dataType"
	"phoenix/phoenix/defines/opcode"
	"phoenix/phoenix/entitys/agentEntity"
	entityBase2 "phoenix/phoenix/entitys/entityBase"
	"phoenix/phoenix/entitys/instance/message"
	"phoenix/phoenix/managers/entityManager"
	"phoenix/phoenix/managers/objectsManager"
	"phoenix/phoenix/managers/worldManager"
	"phoenix/phoenix/utils"
)

type Avatar struct {
	agentEntity.AgentEntity
}

func newAvatar() *Avatar {
	e := &Avatar{
		AgentEntity: agentEntity.AgentEntity{
			ConnectId:  0,
			EntityBase: entityBase2.NewEntityBase(entityType2.EntityName_Avatar, entityType2.EntityType_Avatar),
		},
	}
	entityManager.PhoenixManagerEntity().AddEntity(e)
	return e
}

func (this *Avatar) Init() {
	logger.PhoenixLoggerIns().Debug("Avatar init")
	this.AgentEntity.Init()
}

func (this *Avatar) Release() {
	objectsManager.PhoenixManagerObjects().DestroyObject(this)
	entityManager.PhoenixManagerEntity().RemoveEntity(this.GetId())
	worldManager.PhoenixManagerWorld().LeaveWorld(this.GetId())
}

func (this *Avatar) OnAvatarLogin(avatarId dataType.PhoenixTypeDataBaseId, avatarName string, accountName string) error {
	logger.PhoenixLoggerIns().Debug("Avatar OnLogin")
	entityDataModel := this.EntityModel.GetEntityData().(*entity.AvatarModelData)
	entityDataModel.AvatarId = avatarId
	entityDataModel.AccountName = accountName
	entityDataModel.AvatarName = avatarName
	err := this.LoadEntityData()
	if err != nil {
		return err
	}
	//处理登录时间更新
	entityDataModel.LoginTime = utils.GetNowTimeFormat()
	err = this.EntityModel.UpdateEntityData(true)
	if err != nil {
		return err
	}
	if err != nil {
		return err
	}
	// 返回登录成功
	packet := message.NewPacket(opcode.Opcode_SC_LOGIN)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2CLogin)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		sendMsg.Name = entityDataModel.AvatarName
		sendMsg.CreateTime = entityDataModel.CreateTime
		err = this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	_ = this.HarvestCarrot()
	return nil
}

func (this *Avatar) ReAvatarLogin(avatarId dataType.PhoenixTypeDataBaseId, avatarName string, accountName string) error {
	// 返回登录成功
	packet := message.NewPacket(opcode.Opcode_SC_LOGIN)
	entityDataModel := this.EntityModel.GetEntityData().(*entity.AvatarModelData)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2CLogin)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		sendMsg.Name = entityDataModel.AvatarName
		sendMsg.CreateTime = entityDataModel.CreateTime
		err := this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	_ = this.HarvestCarrot()
	return nil
}

func (this *Avatar) OnGetResources(d interface{}) error {
	logger.PhoenixLoggerIns().Debug("Avatar OnGetResources")
	resModule := this.GetModule(defines.ModuleName_Avatar_Resources).(*avatar.AvatarResourceModule)
	resModuleModelData, err := resModule.GetResources()
	if err != nil {
		return err
	}
	// 返回资源数据
	packet := message.NewPacket(defines.Opcode_SC_GET_RESOURCES)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_GetResources)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		sendMsg.Carrot = resModuleModelData.Carrot
		sendMsg.Clover = resModuleModelData.Clover
		sendMsg.GoldCarrot = resModuleModelData.GoldCarrot
		sendMsg.MinCarrot = resModuleModelData.MinuteCarrot
		err = this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) OnGetRoomInfo(d interface{}) error {
	logger.PhoenixLoggerIns().Debug("Avatar OnGetRoomInfo")
	module := this.GetModule(defines.ModuleName_Avatar_AllRoom).(*avatar.AvatarAllRoomModule)
	datas := module.GetAllRoomInfo()
	packet := message.NewPacket(defines.Opcode_SC_GET_ROOM_INFO)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_GetRoomInfo)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		datas.Iterator(func(key int, value interface{}) bool {
			data := value.(*avatar2.AvatarAllRoomModelData)
			sendMsg.RoomInfos = append(sendMsg.RoomInfos, &protos.RoomInfo{
				Active: data.Active,
				Id:     int32(data.Dbid),
				RoomId: data.RoomId,
				Theme:  data.Theme,
				Name:   data.Name,
			})
			return true
		})
		err := this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) OnGetRoomPmtInfo(d interface{}) error {
	logger.PhoenixLoggerIns().Debug("Avatar OnGetRoomPmtInfo")
	msg := d.(*protos.C2S_GetRoomPmtInfo)
	module := this.GetModule(defines.ModuleName_Avatar_RoomPmt).(*avatar.AvatarRoomPmtModule)
	datas := module.GetRoomPmtInfo(msg.RoomId)
	packet := message.NewPacket(defines.Opcode_SC_GET_ROOM_PMT)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_GetRoomPmtInfo)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		datas.Iterator(func(key int, value interface{}) bool {
			pmtData := value.(*avatar2.AvatarRoomPmtModelData)
			sendMsg.RoomPmtInfo = append(sendMsg.RoomPmtInfo, &protos.RoomPmtInfo{
				Id:       int32(pmtData.Dbid),
				RoomId:   pmtData.RoomId,
				PmtId:    pmtData.PmtId,
				Level:    pmtData.Level,
				PmtLevel: pmtData.PmtLevel,
				Name:     pmtData.Name,
			})
			return true
		})
		err := this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) OnRoomPmtUpLevel(d interface{}) error {
	msg := d.(*protos.C2S_UpRoomPmtLevel)
	module := this.GetModule(defines.ModuleName_Avatar_RoomPmt).(*avatar.AvatarRoomPmtModule)
	packet := message.NewPacket(defines.Opcode_SC_ROOM_PMT_UP_LEVEL)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_UpRoomPmtLevel)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		checkErr := module.CheckCanUpLevelPmt(msg.RoomId, msg.PmtId)
		if checkErr != nil {
			sendMsg.Base.Code = int32(gerror.Code(checkErr).Code())
			sendMsg.Base.Msg = checkErr.Error()
			err := this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		cost, err := module.GetUpLevelCost(msg.RoomId, msg.PmtId)
		if err != nil {
			sendMsg.Base.Code = int32(gerror.Code(err).Code())
			sendMsg.Base.Msg = err.Error()
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		resModule := this.GetModule(defines.ModuleName_Avatar_Resources).(*avatar.AvatarResourceModule)
		re := resModule.CheckResource(defines.GameResType_Carrot, cost)
		if re {
			err = module.UplevelPmt(msg.RoomId, msg.PmtId, false)
			if err != nil {
				sendMsg.Base.Code = int32(gerror.Code(err).Code())
				sendMsg.Base.Msg = err.Error()
			} else {
				resModule.ChangeResource(defines.GameResType_Carrot, -cost)
				pmtData := module.GetPmtInfo(msg.RoomId, msg.PmtId)
				if pmtData != nil {
					sendMsg.RoomPmtInfo = &protos.RoomPmtInfo{
						Id:       int32(pmtData.Dbid),
						RoomId:   pmtData.RoomId,
						PmtId:    pmtData.PmtId,
						Level:    pmtData.Level,
						PmtLevel: pmtData.PmtLevel,
						Name:     pmtData.Name,
					}
				}
				_ = this.HarvestCarrot()
				resModule.ChangeMinuteCarrot(5 * pmtData.Level)
				this.SendResourcesUpdate()
			}
		} else {
			sendMsg.Base.Code = int32(defines.CUSTOMER_ERROR_RES_NOT_ENOUGH)
			sendMsg.Base.Msg = "res not enough"
		}
		err = this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) OnRoomUpCyLevel(d interface{}) error {
	msg := d.(*protos.C2S_UpRoomCyLevel)
	module := this.GetModule(defines.ModuleName_Avatar_RoomPmt).(*avatar.AvatarRoomPmtModule)
	packet := message.NewPacket(defines.Opcode_SC_ROOM_UP_CY_LEVEL)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_UpRoomCyLevel)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		err := module.UpCyLevel(msg.RoomId)
		if err != nil {
			sendMsg.Base.Code = int32(gerror.Code(err).Code())
			sendMsg.Base.Msg = err.Error()
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return err
		}
		datas := module.GetRoomPmtInfo(msg.RoomId)
		datas.Iterator(func(key int, value interface{}) bool {
			data := value.(*avatar2.AvatarRoomPmtModelData)
			sendMsg.RoomPmtInfo = append(sendMsg.RoomPmtInfo, &protos.RoomPmtInfo{
				Id:       int32(data.Dbid),
				RoomId:   data.RoomId,
				PmtId:    data.PmtId,
				Level:    data.Level,
				PmtLevel: data.PmtLevel,
				Name:     data.Name,
			})
			return true
		})
		err = this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) OnHarvestResources(d interface{}) error {
	return this.HarvestCarrot()
}

func (this *Avatar) OnActiveRoom(d interface{}) error {
	msg := d.(*protos.C2S_ActiveRoom)
	packet := message.NewPacket(defines.Opcode_SC_ACTIVE_ROOM)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_ActiveRoom)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		moduleRoom := this.GetModule(defines.ModuleName_Avatar_AllRoom).(*avatar.AvatarAllRoomModule)
		module := this.GetModule(defines.ModuleName_Avatar_RoomPmt).(*avatar.AvatarRoomPmtModule)
		if isActive := moduleRoom.CheckRoomIsActive(msg.RoomId); isActive == true {
			sendMsg.Base.Code = int32(defines.CUSTOMER_ERROR_ROOM_ACTIVED)
			sendMsg.Base.Msg = "店铺已经激活了"
			err := this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		canActive, err := module.CheckCanActiveRoom(msg.RoomId)
		if err != nil {
			sendMsg.Base.Code = int32(gerror.Code(err).Code())
			sendMsg.Base.Msg = err.Error()
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		if canActive == false {
			sendMsg.Base.Code = int32(defines.CUSTOMER_ERROR_ROOM_ACTIVE_FAIL)
			sendMsg.Base.Msg = "店铺激活条件不满足"
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		if err = moduleRoom.ActiveRoom(msg.RoomId); err != nil {
			sendMsg.Base.Code = int32(gerror.Code(err).Code())
			sendMsg.Base.Msg = err.Error()
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		if err = module.ActiveRoom(msg.RoomId); err != nil {
			sendMsg.Base.Code = int32(gerror.Code(err).Code())
			sendMsg.Base.Msg = err.Error()
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		dataRoom := moduleRoom.GetRoom(msg.RoomId)
		if dataRoom == nil {
			sendMsg.Base.Code = int32(defines.CUSTOMER_ERROR_ROOM_ACTIVE_FAIL)
			sendMsg.Base.Msg = "店铺激活失败"
			err = this.SendPacket(packet)
			if err != nil {
				return err
			}
			return nil
		}
		sendMsg.RoomInfo = &protos.RoomInfo{
			Active: dataRoom.Active,
			Id:     int32(dataRoom.Dbid),
			Name:   dataRoom.Name,
			RoomId: dataRoom.RoomId,
			Theme:  dataRoom.Theme,
		}
		err = this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) SendResourcesUpdate() {
	packet := message.NewPacket(defines.Opcode_SC_UPDATE_RESOURCES)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_UpdateResources)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		module := this.GetModule(defines.ModuleName_Avatar_Resources).(*avatar.AvatarResourceModule)
		moduleData, _ := module.GetResources()
		sendMsg.Carrot = moduleData.Carrot
		sendMsg.Clover = moduleData.Clover
		sendMsg.GoldCarrot = moduleData.GoldCarrot
		sendMsg.MinCarrot = moduleData.MinuteCarrot
		_ = this.SendPacket(packet)
	}
}

func (this *Avatar) LoadEntityData() error {
	err := this.GetEntityModel().LoadEntityDataFromDB(nil)
	if err != nil {
		logger.PhoenixLoggerIns().Errorf("load entity %d data error %s", this.Id, err.Error())
		return err
	}
	this.DataBaseID = this.GetEntityModel().GetEntityDBID()
	// 加载模块数据
	avatarModules := this.GetModules()
	for _, module := range avatarModules {
		module.SetEntityDBId(this.DataBaseID)
		err = module.LoadData()
		if err != nil {
			logger.PhoenixLoggerIns().Errorf("load module %s data error %s", module.GetEntityModuleName(), err.Error())
		}
		module.Init()
	}
	return nil
}

func (this *Avatar) LoadEntityModule() error {
	return nil
}

func (this *Avatar) HarvestCarrot() error {
	module := this.GetModule(defines.ModuleName_Avatar_Resources).(*avatar.AvatarResourceModule)
	harvest := module.HarvestCarrot()
	packet := message.NewPacket(defines.Opcode_SC_HARVEST_RESOURCES)
	if packet != nil {
		sendMsg := packet.GetMsg().(*protos.S2C_HarvestResources)
		sendMsg.Base = &protos.S2CBase{
			Code: 0,
			Msg:  "",
		}
		sendMsg.Carrot = harvest
		this.SendResourcesUpdate()
		err := this.SendPacket(packet)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Avatar) SetAccountName(accountName string) {
	this.EntityModel.GetEntityData().(*entity.AvatarModelData).AccountName = accountName
	_ = this.EntityModel.UpdateEntityData(false)
}

func (this *Avatar) SetAvatarName(avatarName string) {
	this.EntityModel.GetEntityData().(*entity.AvatarModelData).AvatarName = avatarName
	_ = this.EntityModel.UpdateEntityData(false)
}

func (this *Avatar) SetLoginTime(loginTime string) {
	this.EntityModel.GetEntityData().(*entity.AvatarModelData).LoginTime = loginTime
	_ = this.EntityModel.UpdateEntityData(false)
}

func (this *Avatar) GetAvatarId() dataType.PhoenixTypeDataBaseId {
	return this.EntityModel.GetEntityData().(*entity.AvatarModelData).AvatarId
}

func (this *Avatar) GetAccountName() string {
	return this.EntityModel.GetEntityData().(*entity.AvatarModelData).AccountName
}

func (this *Avatar) GetAvatarName() string {
	return this.EntityModel.GetEntityData().(*entity.AvatarModelData).AvatarName
}

func (this *Avatar) GetLoginTime() string {
	return this.EntityModel.GetEntityData().(*entity.AvatarModelData).LoginTime
}

func (this *Avatar) GetCreateTime() string {
	return this.EntityModel.GetEntityData().(*entity.AvatarModelData).CreateTime
}

func AvatarObjectCreate() (interface{}, error) {
	return newAvatar(), nil
}

func AvatarObjectDestroy(i interface{}) {
}
